package com.bj58.mis.apm.server.kylin.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 日志分析类
 */
public class KylinLogUtil {

    private static String start1 = "[Query ";
    private static String start2 = "Using project:";

    private static String queryBase = "gtrecord.GTCubeStorageQueryBase:170 :";
    private static String groupsD = "groupsD=[";
    private static String filterD = "filterD=[";
    private static String end = "]";

    private static Map<String, String> keymap = new HashMap<>();
    static{
        keymap.put(start1, "queryTime");
        keymap.put("Query Id","id");
        keymap.put("SQL","sql");
        keymap.put("User","user");
        keymap.put("Success","success");
        keymap.put("Duration","duration");
        keymap.put("Project","project");
        keymap.put("Realization Names","cube");
        keymap.put("Cuboid Ids","cuboIds");
        keymap.put("Total scan count","scanCount");
        keymap.put("Total scan bytes","scanBytes");
        keymap.put("Result row count","resultRow");
        keymap.put("Accept Partial","acceptPartial");
        keymap.put("Is Partial Result","isPartialResult");
        keymap.put("Hit Exception Cache","hitExceptionCache");
        keymap.put("Storage cache used","storageCacheUsed");
        keymap.put("Is Query Push-Down","isQueryPushDown");
        keymap.put("Is Prepare","isPrepare");
        keymap.put("Trace URL","traceURL");
        keymap.put("Message","message");
        keymap.put(groupsD,"groups");
        keymap.put(filterD,"filters");
    }

    /**
     * 读取查询记录
     * @param file 日志文件
     * @return 查询记录
     */
    public static List<Map<String, Object>> readQueryInfo(File file){
        List<Map<String, Object>> list = new ArrayList<>();
        if(file.exists()){
            BufferedReader br = null;
            try {
                br = new BufferedReader(new FileReader(file));
                String str = null;
                Map<String, Object> m = null;
                while((str = br.readLine()) != null){
                    if(str.indexOf(start1) > -1 && str.indexOf(start2) > -1){
                        m = new HashMap<>();
                        str = str.substring(0,23);
                        m.put(keymap.get(start1), TimeUtil.parseDate(str, "yyyy-MM-dd HH:mm:ss,SSS"));
                        continue;
                    }
                    if(str.indexOf(queryBase) > -1 && m != null){
                        String s = str.substring(str.indexOf(groupsD) + groupsD.length(),str.indexOf(end,str.indexOf(groupsD)));
                        s =  s.replaceAll("ODS.","").replaceAll(" ","");
                        m.put(keymap.get(groupsD),s);
                        s = str.substring(str.indexOf(filterD) + filterD.length(),str.indexOf(end,str.indexOf(filterD)));
                        s =  s.replaceAll("ODS.","").replaceAll(" ","");
                        m.put(keymap.get(filterD),s);
                    }
                    if(m != null && m.size() < keymap.size()) {
                        readinfo(str, m);
                    }else if(m != null && m.size() == keymap.size()){
                        deal(m);
                        list.add(m);
                        m = null;
                    }
                }
                br.close();
                br = null;
            }catch (IOException e){
                throw new RuntimeException(e);
            }finally {
                if(br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
        return list;
    }

    /**
     * 读取查询结果
     * @param str 文件一行数据
     * @param info 查询对象
     */
    private static void readinfo(String str,Map info){
        String[] ss = str.split(": ");
        if(ss.length == 2 && keymap.containsKey(ss[0])){
            info.put(keymap.get(ss[0]), ss[1]);
        }
    }

    private static Map<String, Object> deal(Map<String, Object> map){
        //map.put("queryTime", TimeUtil.parseDate((String)map.get("queryTime"), "yyyy-MM-dd HH:mm:ss,SSS"));
        map.keySet().forEach( key -> {
            if("true".equals(map.get(key)) || "false".equals(map.get(key))){
                map.put(key, "true".equals(map.get(key)));
            }

            if("null".equals(map.get(key)) || "NULL".equals(map.get(key))){
                map.put(key, null);
            }
        });

        return map;
    }
}
